package gr.upatras.uniexamtimetable;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/* Forbidden periods for an exam for multiple reasons
 * (for example teacher unavailability) 
 */
/**
 * Periods an exam is forbidden to take place for multiple reasons
 * 
 * @author spirosag
 *
 */
public class ExamForbiddenPeriod {
	private int day;		//day in YYYYMMDD format 
	private int startTime;	//start time in HHMM format
	private int endTime;	//end time in HHMM format

	/**
	 * Constructs an object with the default values
	 */
	public ExamForbiddenPeriod() {
		this.day = 00000000;
		this.startTime = 0000;
		this.endTime = 0000;
	}

	/**
	 * Constructs an object with the given values.
	 * 
	 * @param day	the day in YYYYMMDD format
	 * @param startTime	the starting time in HHMM format
	 * @param endTime	the ending time in HHMM format
	 */
	public ExamForbiddenPeriod(int day, int startTime, int endTime) {
		this.day = day;
		this.startTime = startTime;
		this.endTime = endTime;
	}

	
	/**
	 * @return the day of the forbidden period in YYYYMMDD format
	 */
	public int getDay() {
		return day;
	}

	/**
	 * @param day the day of the forbidden period to set in YYYYMMDD format
	 */
	public void setDay(int day) {
		this.day = day;
	}

	/**
	 * @return the startTime in HHMM format
	 */
	public int getStartTime() {
		return startTime;
	}

	/**
	 * @param startTime the startTime to set in HHMM format
	 */
	public void setStartTime(int startTime) {
		this.startTime = startTime;
	}

	/**
	 * @return the endTime in HHMM format
	 */
	public int getEndTime() {
		return endTime;
	}

	/**
	 * @param endTime the endTime to set in HHMM format
	 */
	public void setEndTime(int endTime) {
		this.endTime = endTime;
	}

	/**
	 * Prints all the characteristics of this object.
	 */
	public void printStatus() {
		System.out.println("Exam forbidden period:");
		System.out.printf("Day: " + day 
				+ "%nStart Time: " + startTime 
				+ "%nEnd Time: " + endTime);
		System.out.printf("%n%n");				//+1 empty line
	}

	/**
	 * Returns the values of this object's variables in a single string 
	 * with explanatory labels.
	 * Overrides the <code>java.lang.Object.toString()</code>
	 * 
	 * @return a string with the values of this objects variables 
	 */
	public String toString() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(String.format("Day: %d, ", day));
		stringBuilder.append(String.format("End time: %d,", endTime));
		stringBuilder.append(String.format("Start time: %d",startTime));
		return stringBuilder.toString();
	}

	/**
	 * Exports a <code>List</code> of <code>ExamForbiddenPeriod</code> objects
	 * to a json file.
	 * 
	 * @param examForbPeriods	the <code>List</code> to be exported
	 * @param filename		the name of file to export to
	 */
	public static void exportToJson(
			List<ExamForbiddenPeriod> examForbPeriods, String filename) {

		BufferedWriter writer = null;
		Gson gson = new Gson();

		System.out.printf("Trying to export to %s ...%n", filename);
		try {
			writer = new BufferedWriter(new FileWriter(filename));

			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<ExamForbiddenPeriod>>(){}.getType();
			gson.toJson(examForbPeriods, collectionType, writer);
		} catch (IOException e) {
			System.err.printf("Sorry, couldn't export to %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				writer.close();
			} catch (IOException e){
				System.err.println("Sorry, couldn't properly close the buffered writer");
				e.printStackTrace();
			}
		}
		
		System.out.printf("Success: %d obcjects were exported.%n", examForbPeriods.size());
	}	

	/**
	 * Imports a <code>List</code> of <code>ExamForbiddenPeriod</code> objects from a json file
	 * 
	 * @param filename	the name of file to import from
	 * @return	a {@code List<ExamForbiddenPeriod> }
	 */
	public static List<ExamForbiddenPeriod> importFromJson(String filename) {

		BufferedReader reader = null;
		Gson gson = new Gson();
		List<ExamForbiddenPeriod> examForbPeriods = null;

		System.out.printf("Trying to import from %s ...%n", filename);
		try {
			reader = new BufferedReader(new FileReader(filename));

			/* ugly way to get the type of List<Room> */
			Type collectionType = new TypeToken<List<ExamForbiddenPeriod>>(){}.getType();
			examForbPeriods = gson.fromJson(reader, collectionType);
		} catch (IOException e) {
			System.out.printf("Sorry, couldn't import from %s.%n", filename);
			e.printStackTrace();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				System.err.println("Sorry, couldn't close the buffered reader.");
				e.printStackTrace();
			}
		}

		System.out.printf("Success: %d obcjects were imported.%n", examForbPeriods.size());
		return examForbPeriods;
	}

}
